﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Pampa.MVC.Breadcrum
{
    public static class BreadcrumHelper
    {
        static BreadcrumNode _rootNode;

        public static BreadcrumNode CurrentNode
        {
            get
            {
                return (BreadcrumNode)HttpContext.Current.Session["BreadcrumCurrentNode"];
            }
            set
            {
                HttpContext.Current.Session["BreadcrumCurrentNode"] = value;
            }
        }

        public static void AddNode(string id, string defaultDescription, string defaultUrl, string parentId = "_ROOT")
        {
            var node = FindNode(RootNode, id);
            if (node != null)
            {
                throw new Exception("There is already a node with id " + id + ".");
            }

            var parentNode = FindNode(RootNode, parentId);
            if (parentNode == null)
            {
                throw new Exception("Node with id " + id + " could not be found.");
            }

            var newNode = new BreadcrumNode();
            newNode.Id = id;
            newNode.DefaultDescription = defaultDescription;
            newNode.DefaultUrl = defaultUrl;
            newNode.Parent = parentNode;
            parentNode.Children.Add(newNode);
        }

        public static void SetCurrentNode(string id, string description, string url)
        {
            var node = FindNode(RootNode, id);

            if (node == null)
            {
                throw new Exception("Node with id " + id + " could not be found.");
            }
            else
            {
                NodesData[node.Id] = new BreadcrumNodeData();
                NodesData[node.Id].Description = description;
                NodesData[node.Id].Url = url;

                CurrentNode = node;
            }
        }

        public static string GetNodeDescription(string id)
        {
            if (NodesData.ContainsKey(id) && NodesData[id].Description != null)
            {
                return NodesData[id].Description;
            }
            else
            {
                var node = FindNode(RootNode, id);

                if (node == null)
                {
                    throw new Exception("Node with id " + id + " could not be found.");
                }
                else
                {
                    return node.DefaultDescription;
                }
            }
        }

        public static string GetNodeUrl(string id)
        {
            if (NodesData.ContainsKey(id) && NodesData[id].Url != null)
            {
                return NodesData[id].Url;
            }
            else
            {
                var node = FindNode(RootNode, id);

                if (node == null)
                {
                    throw new Exception("Node with id " + id + " could not be found.");
                }
                else
                {
                    return node.DefaultUrl;
                }
            }
        }

        private static BreadcrumNode RootNode
        {
            get
            {
                if (_rootNode == null)
                {
                    _rootNode = new BreadcrumNode();
                    _rootNode.Id = "_ROOT";
                }

                return _rootNode;
            }
        }

        private static Dictionary<string, BreadcrumNodeData> NodesData
        {
            get
            {
                if (HttpContext.Current.Session["BreadcrumNodesData"] == null)
                {
                    var nodesData = new Dictionary<string, BreadcrumNodeData>();
                    HttpContext.Current.Session["BreadcrumNodesData"] = nodesData;
                }

                return (Dictionary<string, BreadcrumNodeData>)HttpContext.Current.Session["BreadcrumNodesData"];
            }
        }

        private static BreadcrumNode FindNode(BreadcrumNode node, string id)
        {
            if (node == null || node.Id == id)
            {
                return node;
            }
            else
            {
                var i = 0;
                BreadcrumNode nodeFound = null;
                while (i < node.Children.Count && nodeFound == null)
                {
                    nodeFound = FindNode(node.Children[i], id);
                    i++;
                }
                return nodeFound;
            }
        }
    }
}